#! /usr/bin/env python
#coding=utf-8

class DBTableBase(dict):
	def __init__(self, row, cursor):
		names = [description[0] for description in cursor.description]
		#for idx, field in enumerate(self.__class__.getFields()):
		for idx, name in enumerate(names):
			if idx >= len(row):
				self[name] = ""
				break
			self[name] = row[idx]

	def getFields(self):
		return self.__class__.getFields()

	@classmethod
	def getFieldsStr(cls):
		return ", ".join(cls.getFields())

	@staticmethod
	def getFields():
		return ()

class SymbolBase(DBTableBase):
	def __init__(self, row, mgr):
		super(SymbolBase, self).__init__(row, mgr.getCursor())

        # Add more extended fields
		self["library"] = mgr.find_by_id(self["parent_id"])["name"]

	@staticmethod
	def getFields():
		return ("name", "addr", "bits", "name_type", "section", "parent_id", "id")

class CalledSymbol(SymbolBase):
	def __init__(self, row, mgr):
		super(CalledSymbol, self).__init__(row, mgr)

        # Add more extended fields
		self["caller"] = mgr.find_by_id(self["caller_id"])

	@staticmethod
	def getFields():
		return SymbolBase.getFields() + ("caller_id", )

class Dependency(DBTableBase):
	def __init__(self, row, mgr):
		super(Dependency, self).__init__(row, mgr.getCursor())
		self["caller"] = mgr.find_by_id(self["caller_id"])
		self["callee"] = mgr.find_by_id(self["callee_id"])
		self._symbolClass = CalledSymbol

	def __eq__(self, other):
		if not isinstance(other, Dependency):
			return NotImplemented

		return self["id"] == other["id"]#and self["name"] == other["name"]

	def getCaller(self):
		return self["caller"]
	def getCallee(self):
		return self["callee"]
	def getCalls(self):
		return self["calls"]

	def __str__(self):
		return "(%d:%s[%d] -%d-> %s[%d])" % (self["id"], self["caller"]["name"], self["caller"]["id"], self["calls"], self["callee"]["name"], self["callee"]["id"])

	def __repr__(self):
		return self.__str__()

	def getDependedSymbols(self, cursor, mgr, cls=SymbolBase):
		sqlcmd = "select * from call_details where dependence_id=%d" % (self["id"])
		symbols = []
		cursor.execute(sqlcmd)
		rows = cursor.fetchall()
		for row in rows:
			symbols.append(cls(row, mgr))
		return symbols
